package updatedModels.Utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

import comparisionAndResults.GenericResultValue;
import comparisionAndResults.ResultValue;
import comparisionAndResults.ResultValueMatrix;
import comparisionAndResults.ValueContainer;

import ModelRepresentations.Model;
import ModelRepresentations.ModelObject;

import updatedModels.*;

public class Utils {
	private static int uniqueID = 1;
	
	/**
	 * static methods only
	 */
	private Utils(){
		
	}
	
	/**
	 * returns the string in lowercase and without special characters(keeps only letters and numbers and spaces)
	 * @param string the string to get lowercase and remove special characters on
	 * @return the string in lowercase and without special characters
	 */
	public static String toLowerAndRemoveSpecial(String string){
		String temp = string.toLowerCase();
		
//		System.out.println("0 = " + (int)temp.charAt(0));
//		for(int i = 0; i < temp.length(); i++){
//			if((((int)temp.charAt(i) <= 122) && ((int)temp.charAt(i) >= 97)) || temp.charAt(i) == ' '){
//				temp2 = temp2 + temp.charAt(i);
//			}
//		}
		
		return temp.replaceAll("[^a-z0-9\\x20]", "");
	}
	
	/**
	 * Gets an unique "ID"
	 * @return the id
	 */
	public static String getUniqueID(){
		return Integer.toString(uniqueID++);
	}
	
	/**
	 * sorts the models on size, returns the one with the smallest size first
	 * @param models the models to sort
	 */
	public static void sortModels(ArrayList<Model> models){
		for(int i = 0; i < models.size(); i++){
			int min = models.get(i).getAllModelObjects().size();
			for(int j = i+1; j < models.size(); j++){
				if(models.get(j).getAllModelObjects().size() < min){
					// switch places
					Model tempModel = models.get(i);
					models.set(i, models.get(j));
					models.set(j, tempModel);
				}
			}
		}
	}
	
	/**
	 * prints all the models
	 * @param models
	 */
	public static void printModelArrayList(ArrayList<Model> models){
		for(int i = 0; i < models.size(); i++){
			System.out.println(models.get(i).getAllModelObjects().size());
		}
	}
	
	
	
	/**
	 * displays a generic result value matrix(with ValueContainer)
	 * @param rvm the resultvaluematrix
	 */
	public static void displayGenericTotalResultValueMatrix(ResultValueMatrix rvm){
		ResultValue[][] rv = rvm.getMatrix();
		System.out.print("     ");
		for(int i = 0; i < rv.length; i++){
			System.out.printf("%10s", "model " + i);
		}
		System.out.println();
		
		for(int i = 0; i < rv.length; i++){
			System.out.print("model " + i + " ");
			for(int j = 0; j < rv[i].length; j++){
//				System.out.print("i j" + i + " " + j);
//				if(rv[i][j] == null){
//					System.out.println("rv null");
//				}
//				System.out.print(((GenericResultValue<Float>)rv[i][j]).getValue());
				System.out.printf("%-10.2f", ((GenericResultValue<ValueContainer>)rvm.getValueAt(i, j)).getValue().getTotal());
			}
			System.out.println();
		}
	}
	
	
	
	/**
	 * displays a generic result value matrix(with float)
	 * @param rvm the resultvaluematrix
	 */
	public static void displayGenericFloatResultValueMatrix(ResultValueMatrix rvm){
		ResultValue[][] rv = rvm.getMatrix();
		System.out.print("     ");
		for(int i = 0; i < rv.length; i++){
			System.out.printf("%10s", "model " + i);
		}
		System.out.println();
		
		for(int i = 0; i < rv.length; i++){
			System.out.print("model " + i + " ");
			for(int j = 0; j < rv[i].length; j++){
//				System.out.print("i j" + i + " " + j);
//				if(rv[i][j] == null){
//					System.out.println("rv null");
//				}
//				System.out.print(((GenericResultValue<Float>)rv[i][j]).getValue());
				System.out.printf("%-10.2f", ((GenericResultValue<Float>)rvm.getValueAt(i, j)).getValue());
			}
			System.out.println();
		}
	}
	
	/**
	 * displays a generic resultvaluematrix in procent
	 * @param rvm the resultvaluematrix
	 */
	public static void displayGenericResultValueMatrixProcent(ResultValueMatrix rvm){
		ResultValue[][] rv = rvm.getMatrix();
		System.out.print(" ");
		for(int i = 0; i < rv.length; i++){
			System.out.printf("%10s", "nod " + i);
		}
		System.out.println();
		
		for(int i = 0; i < rv.length; i++){
			System.out.printf("%10s", "nod " + i);
			for(int j = 0; j < rv[i].length; j++){
//				System.out.print("i j" + i + " " + j);
//				if(rv[i][j] == null){
//					System.out.println("rv null");
//				}
//				System.out.print(((GenericResultValue<Float>)rv[i][j]).getValue());
				System.out.printf("%-10.2f", ((GenericResultValue<Float>)rvm.getValueAt(i, j)).getValue()*100);
			}
			System.out.println();
		}
	}
	
	/**
	 * prints a model
	 * @param model to print
	 */
	public static void printModel(Model model){
		if(model == null){
			System.out.println("model == null");
			return;
		}
		for(Model subModel : model.getChildren()){
			printModel(subModel);
		}
		
		for(ModelObject modelObject : model.getModelObjects()){
			printModelObject(modelObject);
		}
		
	}
	
	/**
	 * prints a single ModelObject
	 * @param modelObject the object to print
	 */
	public static void printModelObject(ModelObject modelObject){
		System.out.print("resourceID: ");
		System.out.println(modelObject.getResourceID());
		System.out.print("stencil: ");
		System.out.println(modelObject.getStencil());
		System.out.print("outgoing: ");
		System.out.println(modelObject.getOutgoing());
		System.out.print("target: ");
		System.out.println(modelObject.getTarget());
		printProperties(modelObject.getProperties());
	}
	
	/**
	 * prints the properties contained in the hashmap
	 * @param properties the properties as a hashmap with <what property, the value for that property>
	 */
	public static void printProperties(HashMap<String, String> properties){
		Set<String> tempSet = properties.keySet();
		for(String tempString : tempSet){
			System.out.println(tempString + " : " + properties.get(tempString));
		}
	}
	
	/**
	 * removes the quotes from the string
	 * @param string the string to remove the quotes from
	 * @return the unquoted string
	 */
	public static String removeQuotes(String string){
		return string.replaceAll("\"", "");
	}
	
	
	
	/**
	 * gets the average of a number of numbers
	 * @param numbers is the numbers to get the average of represented as an array
	 * @param total is the total so far as a float
	 * @param divider is the number of numbers currently added together
	 * @return the average
	 */
	public static float getAverage(float[] numbers, float total, int divider){
		if(numbers.length == 0){
			return total/divider;
		}else{
			float[] newNumbers = new float[numbers.length-1];
			System.arraycopy(numbers, 1, newNumbers, 0, numbers.length-1);
			return getAverage(newNumbers, total + numbers[0], divider + 1);
		}
	}
	
	
}
